﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PersonEventHandler
{
    class Person:IPropertyChangeNotification
    {
        private string firstName;
        private string lastName;
        private char gender;
        private string birthDate;

        public string FirstName
        {
            get
            {
                return this.firstName;
            }
            set
            {
                FirstNameValueChanged = new EventHandler(Person_FirstNameValueChanged);
                this.OnFirstNameValueChanged();
                PropertyChanged = new PropertyChangedEventHandler(Person_PropertyChanged);
                OnPropertyChanged("FirstName", this.firstName, value);
                this.firstName = value;
            }
        }

        public string LastName
        {
            get
            {
                return this.lastName;
            }
            set
            {
                
                LastNameValueChanged = new EventHandler(Person_LastNameValueChanged);
                this.OnLastNameValueChanged();
                PropertyChanged = new PropertyChangedEventHandler(Person_PropertyChanged);
                this.OnPropertyChanged("LastName", this.lastName, value);
                this.lastName = value;
            }
        }

        public char Gender
        {
            get
            {
                return this.gender;
            }
            set
            {
                if (value != 'M' && value != 'F')
                {
                    throw new InvalidOperationException("Gender should be either 'M' or 'F'");
                }
                else
                {
                    
                    GenderChanged = new EventHandler(Person_GenderChanged);
                    this.OnGenderChanged();
                    PropertyChanged = new PropertyChangedEventHandler(Person_PropertyChanged);
                    OnPropertyChanged("Gender", this.gender, value);
                    this.gender = value;
                }
            }
        }

        public string BirthDate
        {
            get
            {
                return this.birthDate;
            }
            set
            {
                BirthDateChanged = new EventHandler(Person_BirthDateChanged);
                OnBirthDateChanged();
                PropertyChanged = new PropertyChangedEventHandler(Person_PropertyChanged);
                OnPropertyChanged("BirthDate", this.birthDate, value);
                this.birthDate = value;

            }
        }

        public Person()
            : this(" ", " ", ' ', " ")
        {
        }

        public Person(string firstName, string lastName, char gender, string birthDate)
        {
            this.firstName = firstName;
            this.lastName = lastName;
            this.gender = gender;
            this.birthDate = birthDate;
            this.LastNameValueChanged+= delegate
            {
                Console.WriteLine("Last name changed");
            };

            this.FirstNameValueChanged += delegate
            {
                Console.WriteLine("First name changed");
            };

            this.GenderChanged += delegate
            {
                Console.WriteLine("Gender changed");
            };

            this.BirthDateChanged += delegate
            {
                Console.WriteLine("Birth date changed");
            };
        }

        public event EventHandler FirstNameValueChanged;
        public event EventHandler LastNameValueChanged;
        public event EventHandler GenderChanged;
        public event EventHandler BirthDateChanged;
        //Second version with only 1 event
        public event PropertyChangedEventHandler PropertyChanged;

        private void Person_FirstNameValueChanged(object sender, EventArgs args)
        {
            Console.WriteLine("First name was changed");
        }

        private void Person_BirthDateChanged(object sender, EventArgs args)
        {
            Console.WriteLine("Date of birth was changed");
        }

        private void Person_LastNameValueChanged(object sender, EventArgs args)
        {
            Console.WriteLine("Last name was changed");
        }

        private void Person_GenderChanged(object sender, EventArgs args)
        {
            Console.WriteLine("Gender was changed");
        }
        //Second version Person_ method
        private void Person_PropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            Console.WriteLine("{0} was changed from {1} to {2}", args.nameOfProperty, args.oldValue, args.newValue);
        }

        protected void OnFirstNameValueChanged()
        {
            if (FirstNameValueChanged != null)
            {
                FirstNameValueChanged(this, new EventArgs());
            }
        }

        protected void OnLastNameValueChanged()
        {
            if (LastNameValueChanged != null)
            {
                LastNameValueChanged(this, new EventArgs());
            }
        }

        protected void OnGenderChanged()
        {
            if (GenderChanged != null)
            {
                GenderChanged(this, new EventArgs());
            }
        }

        protected void OnBirthDateChanged()
        {
            if (BirthDateChanged != null)
            {
                BirthDateChanged(this, new EventArgs());
            }
        }

        //second version On method

        protected void OnPropertyChanged(string nameOfProperty, object oldValue, object newValue)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(nameOfProperty, oldValue, newValue));
            }
        }

    }
}
